/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package TeoriaDeColas;

import cern.jet.random.Normal;
import cern.jet.random.engine.DRand;
import cern.jet.random.engine.RandomEngine;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import javax.swing.JLabel;
import javax.swing.JPanel;


/**
 * clase que crea servidores de atencion en el sistema
 * @author Karadak
 */
public class Servidor extends JLabel  implements Runnable
{
    private int clientesAtendidos;              // control de clientes atendidos
    private boolean activo;                     // bandera de actividad 
    private double tiempoServicio;              // tiempo que da el servicio
    private Thread hilo;                        // hilo propio del servidor
    private Semaphore semaforo;                 // control de concurrencias
    private Cliente persona_atendida;           // persona atendida por el servicio
    private ArrayList<Cliente> cola;            // cola del servidor
    private javax.swing.JPanel Panel_Salida;          // panel de animacion de salidas
    private javax.swing.JPanel Panel_alServicio;      // panel de animacion de camino al servicio
    
    /**
     * inicializa propiedades del servidor
     * @param tiempoServicio
     * @param cola 
     */
    public Servidor(double tiempoServicio, ArrayList cola)
    {

        setIcon(new javax.swing.ImageIcon(getClass().getResource("/Iconos/Simulador/tienda.png")));
        setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        setBounds(0,201, 100, 100);
        
        clientesAtendidos = 0;          // inicializamos el contador de personas atendidas
        setText(Integer.toString(clientesAtendidos));
        this.cola = cola;               // la cola del servicio
        activo = true;                  // pasa a modo activo
        this.tiempoServicio = tiempoServicio;   // tasa de servicio del servidor
        hilo = new Thread(this);                // el hilo del servidor
        semaforo = new Semaphore(0, true);      // control de concurrencias
        
        Variables_Globales.hilos.add(hilo);
        hilo.start();
        
    }

    /**
     * controla el hilo de servidores
     */
    @Override
    public void run() 
    {
       try
       {                      
           int tiempo = 1;
           double saliendo;
           
           while (isActivo())
           {
               System.out.println("Cliente "+this.clientesAtendidos);
               
               setIcon(new javax.swing.ImageIcon(getClass().getResource("/Iconos/Simulador/tienda.png")));
               
               Variables_Globales.hay_cola.acquire();      // buffer de cola
               Variables_Globales.mutex.acquire();         // reservamos proceso
               this.setPersona_atendida(cola.get(0));      // politica de cola
               cola.remove(0);                             // atendemos a este usuario
                    
               Variables_Globales.mutex.release();          // liberamos proceso
               Variables_Globales.longitudFila.release();   // capacidad de cola aumenta (se libera espacio)               
               persona_atendida.semaforo_aux.acquire();     // persona esta siendo atendida
                
               this.Panel_alServicio.add(this.persona_atendida);  // agregamos a la animacion la persona caminando al servicio              
              
               persona_atendida.salidaCola();              // sale la persona del sistema
               saliendo = this.Dist_Normal();              // tiempo en salir la persona del sistema
                           
               setIcon(new javax.swing.ImageIcon(getClass().getResource("/Iconos/Simulador/tiendaOcupado.png")));
               
               while (tiempo <= saliendo) 
                {
                    tiempo++;
                    Thread.sleep(Variables_Globales.velocidad_simulador);
                    while(Variables_Globales.pausar_simulador)
                    {
                        Thread.sleep(100);
                    }
                }
                
                
                tiempo = 0;

                setIcon(new javax.swing.ImageIcon(getClass().getResource("/Iconos/Simulador/tienda.png")));
                Variables_Globales.clientela.add(this.getPersona_atendida());   // agregamos el cliente atendido a la lista de control
                
                this.getPersona_atendida().setTiempoServicio(saliendo);         // guardamos el tiempo de servicio
                persona_atendida.semaforo_aux.acquire();
                System.out.println(Variables_Globales.clientela.size()+" Cliente se tardo en servicio: --> "+saliendo + "\n");
                
                this.Panel_Salida.add(this.persona_atendida);                         // agregamos al panel de animacion la persona atendida
                this.getPersona_atendida().terminar();                          // liberamos al cliente
                clientesAtendidos++;                                            // nuestro control de clientes atendidos
                
                setText(Integer.toString(clientesAtendidos));
                persona_atendida = null;                                        // limpiamos variable
                
                while(Variables_Globales.pausar_simulador)
                {
                    Thread.sleep(100);
                }            
        }
       }
       catch (Exception er)
       {
           System.out.println("Error en RUN() Servidor "+er);
           
       }
        
    }

    /**
     * distribucion de atencion en el servicio
     * @return 
     */
    public double Dist_Normal() 
    {
        
        RandomEngine engine = new DRand();    
         // mena, variance, valor x
        Normal normal = new Normal(1 / tiempoServicio, Math.sqrt(1 / tiempoServicio), engine);
        return normal.nextDouble();
    }
    public Cliente getPersona_atendida() {
        return persona_atendida;
    }

    public boolean isActivo() {
        return activo;
    }

    public void setPersona_atendida(Cliente persona_atendida) {
        this.persona_atendida = persona_atendida;
    }

    public void setSalida(JPanel linea_salida) {
        this.Panel_Salida = linea_salida;
    }

    public void setAlServicio(JPanel caminando_al_servicio) {
        this.Panel_alServicio = caminando_al_servicio;
    }   
        
}
